package com.weacar.weixin.controller;


import com.google.gson.GsonBuilder;
import com.weacar.weixin.model.Bonus;
import com.weacar.weixin.model.MsgType;
import com.weacar.weixin.model.User;
import com.weacar.weixin.model.WechatRequestMessage;
import com.weacar.weixin.service.BonusService;
import com.weacar.weixin.service.UserService;
import com.weacar.weixin.util.EncoderHandler;
import com.weacar.weixin.util.LogUtils;
import com.weacar.weixin.util.sms.SmsService;
import com.weacar.weixin.util.sms.SmsServiceException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Fong
 */
@Controller
@RequestMapping("/bonus/A2")
public class A2Controller {

    private static final Logger log = LoggerFactory.getLogger(A2Controller.class);

    @Value("${wechat.token:weixin}")
    private String token;


    @Autowired
    private UserService userService;
    @Autowired
    private BonusService bonusService;
    @Autowired
    private SmsService smsService;



    //~ Request Mapping =============================================================


    /**
     * 微信认证
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @param echostr
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping(value = "", method= RequestMethod.GET)
    public String authorizate(
                       @RequestParam String signature,
                       @RequestParam String timestamp,
                       @RequestParam String nonce,
                       @RequestParam(required = false) String echostr) throws IOException {

        log.debug(String.format("{ signature=%s, timestamp=%s, nonce=%s }",
                signature, timestamp, nonce));

        String[] str = { token, timestamp, nonce };
        Arrays.sort(str);

        String digest = EncoderHandler.encode("SHA1", str[0] + str[1] + str[2]);
        if (digest.equals(signature)) {
            return echostr;
        }
        return "认证失败";
    }

    /**
     * 接收微信message
     *
     * @param msg
     * @param mp
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "", method= RequestMethod.POST)
    public String message(@RequestBody WechatRequestMessage msg,
                          HttpServletRequest request, ModelMap mp) throws Exception {

        log.debug("WechatRequestMessage={}. " + new GsonBuilder().create().toJson(msg));

        String msgType = msg.getMsgType();

        if (MsgType.isEvent(msgType)) {
            return doEvent(msg, mp);
        } else if (MsgType.isText(msgType)) {
            return doText(msg, request, mp);
        //} else if (MsgType.isImage(msgType)) {
        } else {
            return null;
        }
    }

    /**
     * 微信Event消息
     *
     * @param msg
     * @param mp
     * @return
     * @throws Exception
     */
    private String doEvent(WechatRequestMessage msg, ModelMap mp) {
        mp.put("fromUser", msg.getToUserName());
        mp.put("toUser", msg.getFromUserName());
        mp.put("createTime", new Date().getTime());

        if ("subscribe".equals(msg.getEvent())) {
            try {
                Optional<User> user = userService.getUser(msg.getFromUserName());
                if (user.isPresent()) {
                    Optional<Bonus> bonus = bonusService.getBonusByUser(msg.getFromUserName());
                    if (!bonus.isPresent() || (bonus.isPresent() && !StringUtils.equals(bonus.get().getStatus(), "done"))) {
                        mp.put("content", "欢迎关注网车, 回复W+手机号领取红包, 最多只能领取一次哦~, 如: W13112341234");
                        return "text";
                    } else if (bonus.isPresent() && StringUtils.contains(bonus.get().getStatus(), "done")){
                        mp.put("content", "欢迎关注网车, 程序猿还在正在努力奋斗ing哦(www.weacar.com), 请继续关注我们, 期间会有丰富的活动哦!");
                        return "text";
                    }
                } else {
                    userService.subscribe(msg.getFromUserName());
                    mp.put("content", "欢迎关注网车, 回复W+手机号领取红包, 最多只能领取一次哦~, 如: W13112341234");
                    return "text";
                }
            } catch (Exception e) {
                LogUtils.errorException(log, "fromUser=" + msg.getFromUserName(), e);
                mp.put("content", "呜, 我们出错了");
                return "text";
            }

        } else if ("unsubscribe".equals(msg.getEvent())) {
            try {
                userService.unsubscribe(msg.getFromUserName());
            } catch (Exception e) {
                LogUtils.errorException(log, "fromUser="+msg.getFromUserName(), e);
            }
        }

        throw new RuntimeException("Hack!!!");
    }

    /**
     * 微信文本消息
     * @param msg
     * @param mp
     * @return
     */
    private String doText(WechatRequestMessage msg, HttpServletRequest request, ModelMap mp) {
        mp.put("fromUser", msg.getToUserName());
        mp.put("toUser", msg.getFromUserName());
        mp.put("createTime", new Date().getTime());

        String content = msg.getContent();
        if (content.startsWith("W") || content.startsWith("w")) {
            String phone = content.substring(1);
            Pattern pattern = Pattern.compile("^1\\d{10}");
            Matcher matcher = pattern.matcher(phone);
            if (matcher.matches()) {
                try {
                    smsService.sendSmsCode(msg.getFromUserName(), phone);
                    bonusService.initBonus(msg.getFromUserName(), phone);
                    mp.put("content", "短信验证码已发送, 请回复C+短信验证码, 如: C123456");
                    return "text";
                } catch (SmsServiceException e) {
                    mp.put("content", "额, 短信验证码发送失败");
                    return "text";
                }

            } else {
                mp.put("contenet", "亲, 请输入正确手机号哦~");
                return "text";
            }

        } else if (content.startsWith("C") || content.startsWith("c")) {
            String smsCode = content.substring(1);
            Optional<Bonus> bonus = bonusService.getBonusByUser(msg.getFromUserName());
            if (bonus.isPresent()) {
                if (smsService.isSmsCodeValid(bonus.get().getUserName(), bonus.get().getPhone(), smsCode)) {
                    Optional<String> message = bonusService.sendBonus(bonus.get());
                    if (message.isPresent()) {
                        mp.put("content", message.get());
                        return "text";
                    }
                } else {
                    mp.put("content", "亲, 短信验证码不对哦~");
                    return "text";
                }
            } else {
                mp.put("content", "亲, 回复W+手机号领取红包哦, 如: W13112341234");
                return "text";
            }
        }

        throw new RuntimeException();
    }


}
